package cn.ztr.ymcc.web.controller;

import cn.ztr.ymcc.domain.PayZfb;
import cn.ztr.ymcc.service.IPayOrderService;
import cn.ztr.ymcc.domain.PayOrder;
import cn.ztr.ymcc.query.PayOrderQuery;
import cn.ztr.ymcc.result.JsonResult;
import cn.ztr.ymcc.result.PageList;
import cn.ztr.ymcc.util.AssertUtil;
import com.alipay.easysdk.factory.Factory;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mysql.cj.log.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@Slf4j
@RequestMapping("/payOrder")
public class PayOrderController {

    @Autowired
    public IPayOrderService payOrderService;

    /**
     * 保存和修改公用的
     */
    @PostMapping("/save")
    public JsonResult saveOrUpdate(@RequestBody PayOrder payOrder) {
        if (payOrder.getId() != null) {
            payOrderService.updateById(payOrder);
        } else {
            payOrderService.save(payOrder);
        }
        return JsonResult.me();
    }

    /**
     * 删除对象
     */
    @DeleteMapping("/{id}")
    public JsonResult delete(@PathVariable("id") Long id) {
        payOrderService.removeById(id);
        return JsonResult.me();
    }

    /**
     * 获取对象
     */
    @GetMapping("/{id}")
    public JsonResult get(@PathVariable("id") Long id) {
        return JsonResult.me().setData(payOrderService.getById(id));
    }


    /**
     * 查询所有对象
     */
    @GetMapping("/list")
    public JsonResult list() {
        return JsonResult.me().setData(payOrderService.list(null));
    }


    /**
     * 带条件分页查询数据
     */
    @PostMapping("/pagelist")
    public JsonResult page(@RequestBody PayOrderQuery query) {
        Page<PayOrder> page = new Page<PayOrder>(query.getPageNo(), query.getPageSize());
        page = payOrderService.page(page);
        return JsonResult.me().setData(new PageList<PayOrder>(page.getTotal(), page.getRecords()));
    }

    /**
     * 查询支付信息
     *
     * @param orderNo
     * @return
     */
    @GetMapping("/checkPayOrder/{orderNo}")
    public JsonResult checkPayOrder(@PathVariable("orderNo") String orderNo) {
        PayOrder payOrder = payOrderService.getOne(new QueryWrapper<PayOrder>().eq("order_no", orderNo));
        return payOrder != null ? JsonResult.me(payOrder) : JsonResult.error("没有该订单");
    }

    /**
     * 用户支付
     *
     * @param payZfb
     * @return
     */
    @PostMapping("/apply")
    public JsonResult apply(@RequestBody PayZfb payZfb) {
        return payOrderService.apply(payZfb);
    }


    /**
     * 支付宝支付后异步通知
     * @param request
     * @return
     */
    @PostMapping("/asynchronousNotification")
    public String asynchronousNotification(HttpServletRequest request) {
        try {
            log.debug("异步通知调用成功");
            //1 接收参数
            Map<String, String[]> parameterMap = request.getParameterMap();
            Map<String, String> parameters = new HashMap<>();
            //2 取出数组中的元素
            parameters = parameterMap.entrySet().stream().collect(Collectors.toMap(k -> k.getKey(), v -> v.getValue()[0]));
            //3 二次验签
            Boolean flag = Factory.Payment.Common().verifyNotify(parameters);
            if (flag) {
                //4 校验支付状态
                String trade_status = parameters.get("trade_status");
                if (trade_status.equals("TRADE_SUCCESS") || trade_status.equals("TRADE_FINISHED")) {
                    //4.1 支付成功,修改支付信息,添加支付流水,修改订单信息,添加课程购买记录
                    log.debug("支付成功");
                    payOrderService.paySuccess(parameters);
                } else {
                    //4.2 支付失败
                }
                return "success";
            } else {
                // TODO 验签失败则记录异常日志，并在response中返回failure.
                return "failure";
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }
}
